<?php

class Ext_View_Helper_Date extends Zend_View_Helper_Abstract
{
    /**
     * @example нояб. 25
     */
    const FORMAT_MMMDD            = 1;

    /**
     * @example ноября 2011
     */
    const FORMAT_MMMMYYYY         = 2;

    /**
     * @example 2011
     */
    const FORMAT_YYYY             = 3;

    /**
     * @example пятница, ноября 25, 2011 14:30
     */
    const FORMAT_EEEEMMMMddYYYY   = 4;

    /**
     * @example нояб. 25, 2011 14:30
     */
    const FORMAT_MMMDDYYYYHHmm    = 5;

    /**
     * @example нояб. 24 или 14:30
     */
    const FORMAT_DATE_OR_TIME     = 6;

    /**
     * @example 10 hours and 52 minutes
     */
    const FORMAT_TIME_SINCE       = 7;

    /**
     * @example 2011-11-24 14:30
     */
    const FORMAT_YYYY_MM_DD_HH_MM = 8;

    /**
     * @example 1322163000
     */
    const FORMAT_TIMESTAMP        = 9;

    /**
     * @example 25.11.2011
     */
    const FORMAT_DDMMYYYY         = 10;

    /**
     * @example 2011_11_47_4_23
     */
    const FORMAT_YYYY_MM_WW_W_DD  = 11;

    /**
     * @example нояб. 2011
     */
    const FORMAT_MMMYYYY          = 12;

    protected $_dateChucks = array(
        31536000 => 'year',
        2592000  => 'month',
        604800   => 'week',
        86400    => 'day',
        3600     => 'hour',
        60       => 'minute',
        1        => 'second'
    );

    public function date($value = null, $format = 10)
    {
        if (null === $value) {
            $value = Zend_Date::now()->toString('yyyy-MM-dd hh:mm:ss');
        }
        if ($value) {
            $date = new Zend_Date($value, 'yyyy-MM-dd hh:mm:ss', Zend_Registry::get('Zend_Translate')->getLocale());
            switch ($format) {
                case self::FORMAT_MMMDD:
                    return $date->toString(Zend_Date::MONTH_NAME_SHORT . ' ' . Zend_Date::DAY);
                case self::FORMAT_MMMMYYYY:
                    return $date->toString(Zend_Date::MONTH_NAME . ' ' . Zend_Date::YEAR);
                case self::FORMAT_YYYY:
                    return $date->toString(Zend_Date::YEAR);
                case self::FORMAT_EEEEMMMMddYYYY:
                    return $date->toString(Zend_Date::WEEKDAY
                            . ', ' . Zend_Date::MONTH_NAME
                            . ' ' . Zend_Date::DAY
                            . ', ' . Zend_Date::YEAR
                            . ' ' . Zend_Date::TIME_SHORT);
                case self::FORMAT_MMMDDYYYYHHmm:
                    return $date->toString(Zend_Date::MONTH_NAME_SHORT
                            . ' ' . Zend_Date::DAY
                            . ', ' . Zend_Date::YEAR
                            . ' ' . Zend_Date::TIME_SHORT);
                case self::FORMAT_YYYY_MM_DD_HH_MM:
                    return $date->toString(Zend_Date::YEAR_8601
                            . '-' . Zend_Date::MONTH
                            . '-' . Zend_Date::DAY
                            . ' ' . Zend_Date::TIME_SHORT);
                case self::FORMAT_DATE_OR_TIME:
                    if ($date->isToday()) {
                        return $date->toString(Zend_Date::TIME_SHORT);
                    } else {
                        return $date->toString(Zend_Date::MONTH_NAME_SHORT . ' ' . Zend_Date::DAY);
                    }
                case self::FORMAT_TIME_SINCE:
                    return $this->_timeSince($date->toString(Zend_Date::TIMESTAMP));
                case self::FORMAT_TIMESTAMP:
                    return $date->toString(Zend_Date::TIMESTAMP);
                case self::FORMAT_DDMMYYYY:
                    return $date->toString(Zend_Date::DAY . '.' . Zend_Date::MONTH . '.' . Zend_Date::YEAR);
                case self::FORMAT_YYYY_MM_WW_W_DD:
                    $year  = $date->toString(Zend_Date::YEAR);
                    $month = $date->toString(Zend_Date::MONTH);
                    $weekYear  = $date->toString(Zend_Date::WEEK);
                    $day = $date->toString(Zend_Date::DAY);
                    $weekMonth = $weekYear - $date->subDate('0-0-' . ($day - 1), 'yyyy-MM-dd')->toString(Zend_Date::WEEK) + 1;
                    
                    return $year . '_'. $month . '_' . $weekYear . '_' . $weekMonth . '_' . $day;
                case self::FORMAT_MMMYYYY:
                    return $date->toString(Zend_Date::MONTH_NAME_SHORT . ' ' . Zend_Date::YEAR);
            }
        }
        return null;
    }


    /**
     * Formats a date as the time since that date (e.g., “4 weeks ago”).
     *
     * @param integer $timestamp
     * @param integer $time      Timestamp to use instead of time()
     */
    protected function _timeSince($timestamp, $time = null)
    {
        $output     = '';

        if ($time === null) {
            $time = time();
        }

        // Seconds since
        $since = $time - $timestamp;

        foreach ($this->_dateChucks as $seconds => $name) {
            if (!isset($largestChunk)) {
                $ratio = $since / $seconds;
                $chunk = ($since < 0) ? -floor(abs($ratio)) : floor($ratio);
            }

            // Compute chunks
            if (isset($chunk) && $chunk != 0  && !isset($largestChunk)) {
                $largestChunk        = $chunk;
                $largestChunkName    = ($chunk == 1) ? $name : $name . 's';
                $largestChunkSeconds = $seconds;
            } else if (isset($chunk) && $chunk == 0 && !isset($largestChunk)) {
                // Handle if it 0 seconds
                $output = $this->view->t('less than a second');
            } else if (isset($largestChunk)) {
                $ratio = ($since - ($largestChunkSeconds * $largestChunk)) / $seconds;
                $chunk = ($since < 0) ? -floor(abs($ratio)) : floor($ratio);

                if ($chunk != 0) {
                    $secondChunk     = $chunk;
                    $secondChunkName = ($chunk == 1) ? $name : $name . 's';
                }

                break;
            }
        }

        if (isset($secondChunk)) {
            $output = $this->view->t("%d $largestChunkName and %d $secondChunkName", $largestChunk, $secondChunk);
        } else if (isset($largestChunk)) {
            $output = $this->view->t("%d $largestChunkName", $largestChunk);
        }

        return $output;
    }
}